#ifndef LEWC_COMPUTE_H
#define LEWC_COMPUTE_H

#include <string>
#include <vector>
#include <stack>
#include "Word.h"
#include "WordChain.h"
#include "SCComponent.h"

using namespace std;

class Compute {
private:
    vector<vector<Word>> wordsMap;
    vector<Word> linkMap[26][26];
    Word* longestLink[26][26] = { nullptr };

    int node2scc[26] = { 0 };
    Word* longestBridge[26][26] = { nullptr };
    vector<SCComponent> sccList;
    vector<Word> sccLinkList[26];
    vector<Word> sccLinkMap[26][26];

    void getScc();
    std::vector<int> topologicalSort();
    void tarjan(int node, int *num, int *dfn, int *low, vector<int> *stack);
    std::vector<int> topologicalSortForScc();
public:
    Compute(const set<string>& words);

    bool hasCircle();
    bool hasCircle(int headLetter[], Word &word);
    void dfs(std::vector<std::string> *chains, Word &word);
    void dfsMaxWordCHain(Word &word, const char t);

    std::vector<std::string> getAllChains();

    WordChain getDiameterWithCircle(int lengthType);
    WordChain getLongestPathWithCirCleTo(char tail, int lengthType);
    WordChain getLongestPathWithCirCleFrom(char head, int lengthType);
    WordChain getLongestPathWithCirCleBetween(char head, char tail, int lengthType);

//    WordChain getDiameter(int lengthType);
//    WordChain getLongestPathTo(char tail, int lengthType);
//    WordChain getLongestPathFrom(char head, int lengthType);
//    WordChain getLongestPathBetween(char head, char tail, int lengthType);

//    std::string getMaxWordChainNotAllowCircle(const char h, const char t, const char j);
//    std::string getMaxWordChainAllowCircle(const char h, const char t, const char j);
//    std::string getMaxLetterChainNotAllowCircle(const char h, const char t, const char j);
//    std::string getMaxLetterChainAllowCircle(const char h, const char t, const char j);
//    void dfsMaxLetterCHain(Word &word, const char t);
};


#endif //LEWC_COMPUTE_H
